﻿using System.IO.Ports;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace 串口调试工具 {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        SerialPort? m_serialport = null;
        byte[] Buffer = new byte[65536];
        private readonly Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
        public MainWindow() {
            InitializeComponent();
        }

        private void OpenSerial_Click(object sender, RoutedEventArgs e) {
            if (m_serialport != null) {
                if (!m_serialport.IsOpen) {
                    return;
                }
            }
            try {
                int port;
                if (int.TryParse(PortBox.Text, out port)) {
                    int baud;
                    if (int.TryParse(BaudComboBox.Text, out baud)) {
                        int databit;
                        if (int.TryParse(DataBox.Text, out databit)) {
                            m_serialport = new SerialPort(string.Format("COM{0}", port), baud, (Parity)ParityComboBox.SelectedIndex, databit, (StopBits)StopComboBox.SelectedIndex);
                            m_serialport.DataReceived += M_serialport_DataReceived;
                            m_serialport.Disposed += M_serialport_Disposed;
                            m_serialport.ErrorReceived += M_serialport_ErrorReceived;
                            m_serialport.PinChanged += M_serialport_PinChanged;
                            m_serialport.Open();
                            if (m_serialport.IsOpen) {
                                MessageBox.Show(string.Format("COM{0}打开成功", port));
                            }
                        }
                    }
                }
            }
            catch (Exception ex) {
                MessageBox.Show(ex.ToString());
            }

        }

        private void M_serialport_PinChanged(object sender, SerialPinChangedEventArgs e) {
            throw new NotImplementedException();
        }

        private void M_serialport_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) {
            throw new NotImplementedException();
        }

        private void M_serialport_Disposed(object? sender, EventArgs e) {
            //throw new NotImplementedException();
        }

        private void M_serialport_DataReceived(object sender, SerialDataReceivedEventArgs e) {
            //throw new NotImplementedException();
            if (e.EventType == SerialData.Chars) {
                //收到数据
            }
            else {
                //数据结束
                if (m_serialport != null && m_serialport.IsOpen) {
                    try {
                        int num = m_serialport.Read(Buffer, 0, Buffer.Length);
                        if (num > 0) {
                            string msg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff---\n");
                            for (int i = 0; i < num; i++) {
                                msg += Buffer[i].ToString("X2") + " ";
                            }
                            AppendText(msg);
                        }
                    }
                    catch (Exception ex) {
                        MessageBox.Show(ex.ToString());
                    }
                }
            }

        }

        private void SendButton_Click(object sender, RoutedEventArgs e) {
            string strdata = Sendbox.Text;
            strdata = strdata.Replace(" ", "");
            int len = strdata.Length;
            if (len > 0) {
                byte[] byteArray = new byte[strdata.Length / 2];

                for (int i = 0; i < strdata.Length; i += 2) {
                    byteArray[i / 2] = Convert.ToByte(strdata.Substring(i, 2), 16);
                }

                if (byteArray.Length > 0) {
                    if (m_serialport != null && m_serialport.IsOpen) {
                        try {
                            m_serialport.Write(byteArray, 0, byteArray.Length);
                        }
                        catch (Exception ex) {
                            MessageBox.Show(ex.ToString());
                        }
                    }
                }
                //string[] pairs = strdata.Select((ch, index) => new { ch, index })
                //               .GroupBy(x => x.index / 2)
                //               .Select(g => g.FirstOrDefault()?.ch.ToString() + (g.Count() > 1 ? g.Last().ch.ToString() : ""))
                //               .ToArray();

            }
        }

        public void AppendText(string text) {
            if (dispatcher.CheckAccess()) {
                // 当前线程是UI线程，直接操作
                if (RecvRichTextBox.Document.Blocks.Count > 1024) {
                    RecvRichTextBox.Document.Blocks.Clear();
                }
                RecvRichTextBox.AppendText(text);
            }
            else {
                // 使用Invoke方法在UI线程中调用
                dispatcher.Invoke(() => {
                    if (RecvRichTextBox.Document.Blocks.Count > 1024) {
                        RecvRichTextBox.Document.Blocks.Clear();
                    }

                    RecvRichTextBox.AppendText(text);
                });
            }
        }
    }
}